概述
这几天断断续续的在看Spring实战,主要看了前两章的东西,特此记录一下。
依赖注入
作为Spring最为核心的概念,依赖注入(Dependency Injection,DI)这个名词既绕口,也没那么好理解。他其实是一种软件工程设计原则控制反转(Inversion of Control,IoC)的一种实现。
究其目的,是为了能够减少面向对象软件工程中多对象之间耦合度太高的问题。具体到Spring框架来说,在Spring的世界观里面,对象之间的创建与调用都应该由Spring的IoC容器来负责,而不应该由对象之间相互调用,这种设计思想,可以能够很好的减少对象之间的相互耦合。而在Spring中如何自动的创建对象实例bean呢,这种行为在Spring中的名词就是装配(Wiring)。随着框架的完善,今天的Spring主要以三种方式来完成对Java Bean的装配。
装配方式
自动装配
Spring发展到如今,自动化的程度很高,自动装配也是非常方便并且在Spring Boot框架中大量使用。在Spring实战这本书中,也属于重点介绍的技术,Spring技术主要通过两个角度来实现自动化的装配:
- 组件扫描(component scanning):Spring自动发现应用上下文中(ApplicationContext)所创建的bean
- 自动装配(autowiring): Spring自动的满足bean之间的相互依赖
举个例子可以很清楚的看见Spring是如何通过自动装配的方式来完成自动的装配。假设以Spring Boot框架为例,有一个Singer去演唱一首歌,那么当他需要唱歌时需要哪些东西呢,在Spring的自动装配中,比较简单。首先需要定义能够唱歌的灵魂歌手LeiJun:
1 |
|
光有人是不够的,如何能够唱歌呢,注入进来就好了!
1 | (SpringRunner.class) |
在Spring中,利用自动装配去使用一个对象就这么简单,依靠@Component
注解与@Autowired
注解就能够完成对一个对象的使用,但其实在这背后,Spring默默的为我们做了很多的事情。首先,当为一个对象定义为@Component
注解时,相当于对Spring声明了这个类将会作为组件类,并且告知Spring要为这个类创建bean,当然,组件的扫描并不是直接启动的,需要通过对Spring的配置从而启动对所有@Component
的注解的扫描,并创建相应的bean,以Spring Boot为例,在其启动时会有一个@SpringBootApplication
注解,这其实是个多重注解的组合,
1 | (ElementType.TYPE) |
其中,ComponentScan
的作用尤为重要,在项目启动的时候,该注解会去扫描根据配置好的Package下的类,在本例中,他就会将加载了@Component
注解的LeiJun
加载入Ioc容器中并自动为其创建一个bean,而如单元测试中例子所示,当在Spring框架中需要引用一个bean时,通过@Autowired
将其从IoC容器中注入进来就可以使用了。
以上,就是通过自动装配的姿势,让LeiJun
唱歌的过程。
JavaConfig装配
并不是任何时候自动配置都是合适的场景,这种时候 ,总需要去执行Plan B,此时,可能就需要我们对JavaBean进行的显示的配置了,JavaConfig的装配方式比较特殊,因为他就是Java代码,就像程序中的其他代码一样,只不过不包含任何业务逻辑,显得比较独立。再以一位歌手为例,就能清楚JavaConfig的配置方式。首先,都需要定义一位歌手:
1 | public class GongLinNa implements Singer{ |
相比较上次而言,这位歌手并没有一个Component注解,这是因为她没有选择通过自动装配的方式注入进IoC容器的缘故,通过JavaConfig,可以达到同样的目的!
1 |
|
同样也可以唱歌:
1 | (SpringRunner.class) |
如方式一相比,能够明显的观察出不同,少了一个@Component
注解,多了一个SingerConifg
类。这个类中,多了两个注解@Configuration
和@Bean
。其实从名字就能够看出,Configuration
表明应用了这个注解的Java类就是一个Java配置类,而@Bean
则表明了这个方法将为Spring返回一个Bean,通过这种方式,Spring同样能够将其注入进来,并在其他的地方注入使用。相比较与自动注入而言,这种要稍微繁琐一点。使用场景,以Spring Boot为例,Spring Boot 各种起步starter中的很多基础包都是以这种方式配置,并且通过EnableAutoConfiguration
将符合条件的配置加载到容器中来并且使用。
XML方式
xml方式的配置方式,在Spring中,有着悠久的历史。简而言之,类似与JavaConfig方式,只不过这种bean的方式并不是通过Java代码,而是xml的方式进行约定。由于其历史的悠久性,注定了其繁琐程度也要大大高于另外两种方式,在如今的项目工程中,实际使用的也并不多。通常情况下,自动装配和JavaConfig就已经足够使用了。
常用注解
Spring并不会通过强制约定项目代码去实现一个Spring规范的接口或者集成Spring规范的类,通常来说,当需要使用起Spring的特性,注解是必不可少的,在进行依赖注入的使用过程中,以下的几个注解是我能够经常看到的。
@Component
: 这个简单的注解通常注解在类上,表明这个类是Spring的一个组件,而Spring看到这样的类,当配置了自动扫描时,将会自动将其收集到容器中并为其创建bean。
@Service
@Controller
@Repository
: 虽然Component
注解非常好用,但在实际的应用过程中,这三个注解其实是更常用的。以@Service
为例:
1 | ({ElementType.TYPE}) |
可以发现,它上面也有一个@Component
注解,为什么要使用他们而不是直接使用@Component
呢,其实只是为了表意更清楚而已,Service
表明这是一个Service层的对象,Controller
表明这是一个控制层组件,而Repository
则表明这是一个与数据访问相关的组件。
@ComponentScan
: 自动扫描注解,这个注解通常配置在Spring应用启动时,当启动应用时,ComponentScan
注解就可以去搜集所有已经声明了的组件并将它们组装入容器中。
@Autowired
: 当Bean已经在容器时,一个Atuowired
即可注入到当前类中并进行使用.
@Configuration
: 标注在类上,表明这是一个JavaConfiguration类.
@Bean
标注于方法上面,表面将返回一个JavaBean.